.wasm files are the binary executable format for WebAssembly, while .wat files are the human-readable textual representation, similar to how .exe compares to source code.
The .wasm and .wat file extensions represent two different views of the same WebAssembly module: .wasm is the compact binary format that browsers execute, while .wat (WebAssembly Text Format) is a human-readable, S-expression-based syntax designed for developers to read, write, and debug Wasm code. Think of the relationship like that between a compiled .exe file and the original source code—they represent the same program but serve entirely different purposes.
Binary encoding: .wasm files contain a dense binary format where instructions, types, and sections are encoded as bytes for efficient transmission and decoding .
Compact size: The binary format is typically 20-50% smaller than equivalent minified JavaScript, and 10-20x smaller than .wat text .
Fast decoding: Browsers can validate and decode .wasm in a single linear pass, streaming compilation as the file downloads .
Not human-readable: Opening a .wasm file in a text editor shows gibberish—it's meant for machines, not humans .
Magic number: All .wasm files start with the byte sequence 0x00 0x61 0x73 0x6d (\0asm) to identify them as WebAssembly modules .
S-expression syntax: .wat uses Lisp-like parentheses to express nested structures: (module (func $add (param i32 i32) (result i32) (i32.add (local.get 0) (local.get 1)))) .
Human-readable: Designed for developers to read, write, and debug. You can author .wat directly and assemble it to .wasm using tools like wat2wasm .
One-to-one mapping: Every .wat file can be assembled to an equivalent .wasm binary, and any .wasm can be disassembled back to .wat (though variable names may be lost) .
Debugging aid: Browser DevTools can display .wasm modules as .wat, making it possible to step through Wasm code during debugging .
Two syntax flavors: The official spec uses folded S-expressions, but an alternate 'flat' syntax also exists (though less common) .
wat2wasm: Converts .wat to .wasm (part of the WebAssembly Binary Toolkit, WABT) .
wasm2wat: Disassembles .wasm back to .wat for inspection .
wasm-objdump: Shows detailed section information from .wasm binaries .
wasm-validate: Checks if a .wasm file is valid WebAssembly .
wat2wasm demo: Online playground at https://webassembly.github.io/wabt/demo/wat2wasm/ .
Emscripten: Compiles C/C++ directly to .wasm (not .wat) .
In practice, developers rarely write .wat directly. They write in higher-level languages (Rust, C, Go) and compile to .wasm. However, .wat is invaluable for understanding what the compiler produced, debugging performance issues, and learning WebAssembly internals. When you see a .wat file in a blog post or documentation, it's the equivalent of seeing assembly code in a compiler tutorial—it shows what's really happening under the hood.
The .wat format also serves as a compilation target for educational tools and experimental languages. It's possible to generate .wat programmatically and assemble it, skipping the complexity of binary generation. This has led to interesting projects like AssemblyScript (TypeScript-like syntax compiling to Wasm) and various Wasm-focused teaching tools. Ultimately, the .wasm/.wat duality reflects WebAssembly's design philosophy: a compact, efficient binary for production paired with a human-readable representation for development and debugging.